package top.yuhaitao;

import java.io.File;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.io.FileUtils;
import org.codehaus.xfire.util.Base64;

/**
 * 
 *
 * @author garnett.xx
 * @version $Id: SignatureUtil.java, v 0.1 2016年4月29日 上午11:12:07 garnett.xx Exp
 *          $
 */
public class SignatureUtil {

	/** 换行 */
	private static final String NEW_LINE = "\n";

	/** 算法 */
	private static final String ALGORITHM = "SHA256withRSA";

	private static final String public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlgKTIeLGch+oHuRapFFYwGADzCWLgE+g1wUBZdzdxQ9uf195dHpdN7xRma9l/vbImTY9RxOyW5FLvd9DTlIdLWuzBMt15YGaIsUrLmjiZ14rxfBr0MttkNqbntxqixTRktM3cQBNztWQrjB7EL1VUttvC9hfAZVXJhfCH21z5Xk+GNwmk5i1p3XGbmBmrSD69VnOcquT7m7+27Cn9ArCEntsNA6c+KVAjbMgZ0gsMnIzUzZ7j4f5hwNjreEzObbqzENXtGVB83z9vcrvbixJ3Kg9a3veMymHzS98SPedZ1pyb+XTFg4XQRztEPf0O8tgE5aGEDHNvp6g0eCi19+i+QIDAQAB";

	private static final String private_key = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCWApMh4sZyH6ge5FqkUVjAYAPMJYuAT6DXBQFl3N3FD25/X3l0el03vFGZr2X+9siZNj1HE7JbkUu930NOUh0ta7MEy3XlgZoixSsuaOJnXivF8GvQy22Q2pue3GqLFNGS0zdxAE3O1ZCuMHsQvVVS228L2F8BlVcmF8IfbXPleT4Y3CaTmLWndcZuYGatIPr1Wc5yq5Pubv7bsKf0CsISe2w0Dpz4pUCNsyBnSCwycjNTNnuPh/mHA2Ot4TM5turMQ1e0ZUHzfP29yu9uLEncqD1re94zKYfNL3xI951nWnJv5dMWDhdBHO0Q9/Q7y2ATloYQMc2+nqDR4KLX36L5AgMBAAECggEBAIlhykXaXkveWiYQlEKwjUuBo3ivWdclFfRWDTWw1RnITDYyxhS6i+yjd0f8rriWYpiOaAhULaBWrLszYXy1Dyut2sGlZE/QJc16LVXPkKmCQSyCRvttkuZ6jtMqohjF9Dk3XysKUDgAtwQQOmTWQPIlLMn4WuokTy//yjTmFKIuxIXXAJyBoILaq6muxvjKlqZygP/a/k26dhwQ9e/v/W4EvsxF7b0Bttgx453zE5fmSON9uWuvqeWFn1gra+IP6yqyboZnmxxNtlXHEFJ+4TIrXsTIZpJ2ctwVq50bZvbFDb7HxCQM7y6np4Iy09hiEl5EG1MNUdPJ7/IC3aciFJECgYEAxz/pTIaw3fjualmoohQ615GfAAk+DEuGsdTzqkf942lolHk9TEsCiGNKw0tmauTzAlH2wvpo1gh4pMWn05ez6K9/v0sB5Dq+rouwxzAmwv3JXFX9DW3BS3o4/GY2yA+dU5fU/pEmeA6waNPRKZT+mNd0PtMKE6x3cdq8ZQymog8CgYEAwLxoW3ojNds3Bp74OLdUQI82lghD/oOhoo8tyiCEccBruhcqZiVAou8D6NJsP+HrWsv00caK7FTC/flTETJ8Jyy57wJ3nGvP2pYKGAcWsQYXZfRH+/lwVX7KUBppDehdVoPC0JzsCz7znPyIGUWcxiQ867XXgJrUXt9y7ZTm0ncCgYEAsiyvxnQHw2dwY//rMYzflZet1I1vQ/Vh7LJedt5L5kmDcIn+S7Qj/qyz1XIekuZLfL6o6HCewQ7wO4BY9HkLM7+EgB5mAZ6al2FpYqXnc6UYpI5sbM7B9GnGfcY1pK9545+5oy9PdDrGe+c2enW3Ohwo4mk78J3gbhrJL5+hfvcCgYACP/DD6JgSn91zkVV6bAFqw4EynSQWC3lOiXdSXbDOFx3qzSxshtDLVhjoldQ3pq51n93auQOUIKUqC8gBcmJqnqYI+TFmPQfvGEND5olIRbbuNLzGXzIFfXZlGvnQ9L5qLR2QC9ThiLmVQolgKiTbVz7yzWuXj7cc6GTSCyPqnwKBgBB1aePzmcooAXoUUgHLtcAmyslSP0kIJm21Ubn5nCqxjXh2Q8yoOcvxDMjrD114BMzU9iTWZCQk2erTiw4PmMADsD4VdIlWJAvNIOj786aYbcf9wSS1+8zUYbY3F/NXCuC8q8DZwU40EUa13nD20doOh6hm8vqy0IMCcKwDQWf2";

	public static void main(String[] args) throws Exception {

		File file = new File("test.xml");
		String fileContent = FileUtils.readFileToString(file, "UTF-8");

		String encrypt = Base64.encode(fileContent.getBytes("UTF-8"));
		System.out.println(encrypt);
		// String signed = sign(encrypt, private_key);

		String signed = "lRU56N0CyLzsreoU/Ewf8R3W3qdCqYXDWumCe/+oodktgxXg7SNn/S2Ccph+/o4nUPcOABLqKcKqSqEtWHH4q6A5aQaqGCquohHO0ozpS8QQ88viyTMb9eC9QMO+T0YjTdps70AvbdPukkFaJG6APyacQgIRoXbdH8E76HT7faQuNe7AnaQBbokT/cNafyyUwHxQVz6r6EqpVt2oYMIC0DfFPF2837LowmDC4kF4Grq+rCAVtzSMneGrQqkfvL20WWxJrz0M6eCFuZme+4RPMwHEHFcivErNpk/B9TqAMKmQtmjcebjFnhxffK4CEjpf/TTHImgHr5gQsfHwsK9uKg==";
		System.out.println(signed);
		System.out.println(verify(encrypt, signed, public_key));
		String ss = "CQk8aGVhZD4NCgkJCTx2ZXJzaW9uPjMuMDwvdmVyc2lvbj4NCgkJCTxmdW5jdGlvbj5hbnQuYnhjbG91ZC5jb3JlLmlzc3VlPC9mdW5jdGlvbj4NCgkJCTx0cmFuc1RpbWU+MjAxNjEwMjgxNzQwMDI8L3RyYW5zVGltZT4NCgkJCTx0cmFuc1RpbWVab25lPlVUQys4PC90cmFuc1RpbWVab25lPg0KCQkJPHJlcU1zZ0lkPjIwMTYxMDI4MTEwNDAwMDMwMDcxNDMxMDA5Mzg5NDc3PC9yZXFNc2dJZD4NCgkJCTxmb3JtYXQ+WE1MPC9mb3JtYXQ+DQoJCQk8c2lnblR5cGU+UlNBPC9zaWduVHlwZT4NCgkJCTxhc3luPjA8L2FzeW4+DQoJCQk8Y2lkPlRQQlg8L2NpZD4NCgkJPC9oZWFkPg0KCQk8Ym9keT4NCgkJCTxwb2xpY3k+DQoJCQkJPHBvbGljeU5vPjE2MTAyODQ0NTIxNjQ5Mnh4eHh4PC9wb2xpY3lObz4NCgkJCQk8cHJvZE5vPkYwMDUwMDAwMDAwMDAwMDAxMjI4PC9wcm9kTm8+DQoJCQkJPG91dFByb2RObz54eHh4PC9vdXRQcm9kTm8+DQoJCQkJPHN1bW1hcnlQb2xpY3lObz48L3N1bW1hcnlQb2xpY3lObz4NCgkJCQk8cG9saWN5VHlwZT4yPC9wb2xpY3lUeXBlPg0KCQkJCTxwcmVtaXVtPjMwMDwvcHJlbWl1bT4NCgkJCQk8YWN0dWFsUHJlbWl1bT4zMDA8L2FjdHVhbFByZW1pdW0+DQoJCQkJPHN1bUluc3VyZWQ+MTAwMDAwMDwvc3VtSW5zdXJlZD4NCgkJCQk8aW5zdXJlZFRpbWU+MjAxNjEwMjgxNzM5MzI8L2luc3VyZWRUaW1lPg0KCQkJCTxpc3N1ZVRpbWU+MjAxNjEwMjgxNzM5Mzk8L2lzc3VlVGltZT4NCgkJCQk8ZWZmZWN0U3RhcnRUaW1lPjIwMTYxMTAxMDAwMDAwPC9lZmZlY3RTdGFydFRpbWU+DQoJCQkJPGVmZmVjdEVuZFRpbWU+MjAxNzEwMzEyMzU5NTk8L2VmZmVjdEVuZFRpbWU+DQoJCQkJPGFwcGx5TnVtPjE8L2FwcGx5TnVtPg0KCQkJCTxleHRlbmRJbmZvcz48L2V4dGVuZEluZm9zPg0KCQkJPC9wb2xpY3k+DQoJCQk8YmlsbHM+DQoJCQkJPGJpbGw+DQoJCQkJCTxtZXJjaGFudEFjY291bnRUeXBlPjE8L21lcmNoYW50QWNjb3VudFR5cGU+DQoJCQkJCTxtZXJjaGFudEFjY291bnRJZD4yMDg4MjIxNTU3NXh4eHh4PC9tZXJjaGFudEFjY291bnRJZD4NCgkJCQkJPG90aGVyQWNjb3VudFR5cGU+MTwvb3RoZXJBY2NvdW50VHlwZT4NCgkJCQkJPG90aGVyQWNjb3VudElkPjIwODgwMTI3NjY2eHh4eHg8L290aGVyQWNjb3VudElkPg0KCQkJCQk8cGF5VGltZT4yMDE2MTAyODE3MzkzOTwvcGF5VGltZT4NCgkJCQkJPGZlZT4zMDA8L2ZlZT4NCgkJCQkJPHBheUZsb3dJZD4yMDE2MTAyODEwMDAyMDAxODYwMjc0MDV4eHh4PC9wYXlGbG93SWQ+DQoJCQkJPC9iaWxsPg0KCQkJPC9iaWxscz4NCgkJCTxpbnNPYmplY3Q+DQoJCQkJPHR5cGU+OTk8L3R5cGU+DQoJCQkJPGV4dGVuZEluZm9zPjwvZXh0ZW5kSW5mb3M+DQoJCQk8L2luc09iamVjdD4NCgkJCTxwcm9wb3NhbD4NCgkJCQk8cHJvcG9zYWxObz5QNzkyeHh4eDwvcHJvcG9zYWxObz4NCgkJCTwvcHJvcG9zYWw+DQoJCQk8aG9sZGVyPg0KCQkJCTxwZXJzb25Obz4xNjEwMjg5MDQ4Mjc4ODIyeHh4eDwvcGVyc29uTm8+DQoJCQkJPGFjY291bnRUeXBlPjE8L2FjY291bnRUeXBlPg0KCQkJCTxhY2NvdW50Tm8+MjA4ODAxMjc2NjY4eHh4eDwvYWNjb3VudE5vPg0KCQkJCTxhY2NvdW50TmFtZT54eHhAcXEuY29tPC9hY2NvdW50TmFtZT4NCgkJCQk8Y2VydFR5cGU+MTAwPC9jZXJ0VHlwZT4NCgkJCQk8Y2VydE5vPjEzMDQzNDE5ODkwMzI2eHh4PC9jZXJ0Tm8+DQoJCQkJPGNlcnROYW1lPumDrXg8L2NlcnROYW1lPg0KCQkJCTxleHRlbmRJbmZvcz4NCgkJCQkJPGV4dGVuZEluZm8ga2V5PSJwaG9uZSIgdmFsdWU9IjE1MjAxMnh4eHh4IiAvPg0KCQkJCQk8ZXh0ZW5kSW5mbyBrZXk9ImVtYWlsIiB2YWx1ZT0ieHh4eEBxcS5jb20iIC8+DQoJCQkJCTxleHRlbmRJbmZvIGtleT0idXNlck5hbWUiIHZhbHVlPSJ4eHh4QHFxLmNvbSIgLz4NCgkJCQk8L2V4dGVuZEluZm9zPg0KCQkJPC9ob2xkZXI+DQoJCQk8aW5zdXJlZHM+DQoJCQkJPGluc3VyZWQ+DQoJCQkJCTxzYW1lV2l0aEhvbGRlcj4xPC9zYW1lV2l0aEhvbGRlcj4NCgkJCQk8L2luc3VyZWQ+DQoJCQk8L2luc3VyZWRzPg0KCQk8L2JvZHk+";
		System.out.println(new String(Base64.decode(ss), "UTF-8"));
		// System.out.println(verify3("test",signed,public_key));
		// System.out.println(verify2("test", signed, public_key));
	}

	/**
	 * 加签
	 * 
	 * @param text       待加签文本
	 * @param privateKey 加签私钥
	 * @return
	 */
	public static String sign(String text, String privateKey) {
		try {
			byte[] signBytes = sign(Base64.encode(text.getBytes()).getBytes(), Base64.decode(privateKey), ALGORITHM);
			return new String(Base64.encode(signBytes)).replace(NEW_LINE, "");
			// return (new Base64()).encodeBuffer(signBytes).replace(NEW_LINE, "");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 *
	 * @param text
	 * @param privateKeyData
	 * @param algorithm
	 * @return
	 * @throws GeneralSecurityException
	 */
	private static byte[] sign(final byte[] text, final byte[] privateKeyData, final String algorithm) throws GeneralSecurityException {
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyData);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		Signature signatureChecker = Signature.getInstance(algorithm);
		signatureChecker.initSign(privateKey);
		signatureChecker.update(text);
		return signatureChecker.sign();
	}

	/**
	 * 验签
	 * 
	 * @param text       待验签字符串
	 * @param signedText 加签串
	 * @param publicKey  验签公钥
	 * @return
	 */
	public static boolean verify(String text, String signedText, String publicKey) {
		try {
			return verify(Base64.encode(text.getBytes()).getBytes(), Base64.decode(signedText), Base64.decode(publicKey), ALGORITHM);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static boolean verify3(String text, String signedText, String publicKey) {
		try {
			return verify(text.getBytes(), Base64.decode(signedText), Base64.decode(publicKey), ALGORITHM);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 验签
	 * 
	 * @param text       待验签字符串
	 * @param signedText 加签串
	 * @param publicKey  验签公钥
	 * @return
	 */
	public static boolean verify2(String text, String signedText, String publicKey) {
		try {
			return verify(org.apache.commons.codec.binary.Base64.encodeBase64(text.getBytes()), org.apache.commons.codec.binary.Base64.decodeBase64(signedText.getBytes()),
					org.apache.commons.codec.binary.Base64.decodeBase64(publicKey.getBytes()), ALGORITHM);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 *
	 * @param text
	 * @param signedText
	 * @param publicKeyData
	 * @param algorithm
	 * @return
	 * @throws GeneralSecurityException
	 */
	private static boolean verify(final byte[] text, final byte[] signedText, final byte[] publicKeyData, final String algorithm) throws GeneralSecurityException {
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyData);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PublicKey publicKey = keyFactory.generatePublic(keySpec);
		Signature signatureChecker = Signature.getInstance(algorithm);
		signatureChecker.initVerify(publicKey);
		signatureChecker.update(text);
		// System.out.println("signedText is "+signedText.toString());
		return signatureChecker.verify(signedText);
	}

}